from fastapi import Request
from pydantic import BaseModel
from tortoise.transactions import atomic, in_transaction

from service import RepositoryService, UserService, CollaboratorService, BookService
from common.result.Result import Result
from common.enum import BaseEnum
from common.const import BaseConstant
from util.str import Str
from util.log import Log
from util.token import Token
from util.time import Time
from util.redis import Redis

class Body(BaseModel):
    repositoryShortUri: str
    dropNodeId: int
    toNodeId: int
    place: str

BEFORE = 'before'
AFTER = 'after'
INNER = 'inner'

"""
不需要做鉴权, 因为只是修改一下仓库内book的顺序
"""
async def UpdateBookTreeNode(req: Request, body: dict):
    try:
        async with in_transaction() as connection:
            repositoryShortUri = body.get("repositoryShortUri")
            dropNodeId = body.get('dropNodeId')
            toNodeId = body.get("toNodeId")
            place = body.get("place")
            if Str.isBlank(repositoryShortUri, dropNodeId, toNodeId, place):
                Log.error('参数为空，检查参数')
                return Result.error(BaseEnum.PARAMETER_INVALID_ERROR)
            
            token = req.headers.get("token")
            user = await UserService.getUserByToken(token)
            if user == None:
                Log.error('用户不存在')
                return Result.error(BaseEnum.USER_NOT_EXISTS_ERROR)
            
            # 获取 repository
            repository = await RepositoryService.getRepositoryByShortUri(repositoryShortUri)
            if repository == None:
                Log.error('repository 不存在')
                return Result.error(BaseEnum.REPOSITORY_NOT_EXISTS_ERROR)
            
            # 校验修改权限
            flag = await RepositoryService.getUserWritePermission(repository, user.id)
            if flag == False:
                Log.error('该 repository 不允许该用户写')
                return Result.error(BaseEnum.REPOSITORY_NO_WRITE_PERMISSION_ERROR)

            dropBook = await BookService.getBookById(dropNodeId)
            toBook = await BookService.getBookById(toNodeId)
            if dropBook == None or toBook == None:
                Log.error('book 不存在')
                return Result.error(BaseEnum.BOOK_NOT_EXISTS_ERROR)

            # 更新其他需要改变 sort_order 的 book
            cnt = await BookService.updateBookWhenDropNode(dropBook, toBook, place)
            # 单独修改 dropBook
            dropCnt = 0
            if place == BEFORE:
                # dropBook 放到 toBook 之前
                dropCnt = await BookService.updateBookById(dropNodeId, {
                    "parent_id": toBook.parent_id,
                    "sort_order": toBook.sort_order - 1 if toBook.sort_order > 0 else 0
                })
            elif place == AFTER:
                # dropBook 放到 toBook 之后
                dropCnt = await BookService.updateBookById(dropNodeId, {
                    "parent_id": toBook.parent_id,
                    "sort_order": toBook.sort_order + 1
                })
            elif place == INNER:
                # dropBook 放到 toBook 的子节点
                dropCnt = await BookService.updateBookById(dropNodeId, {
                    "parent_id": toBook.id,
                    "sort_order": 0
                })
            if dropCnt == 0:
                Log.error('修改 dropBook 失败')
                return Result.error(BaseEnum.BOOK_UPDATE_ERROR)

            # 删除 tree 的缓存
            key = BaseConstant.BOOK_TREE_KEY % repositoryShortUri
            Redis.deleteItem(key)

            return Result.success({
                "cnt": cnt,
                "dropCnt": dropCnt
            })
    except Exception as e:
        Log.error('修改 book 的树形节点关系异常', e)
        return Result.error(BaseEnum.SERVICE_ERROR)
